package com.clever.config.handler;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.clever.bean.model.WebSocketMessagePayload;
import com.clever.bean.shopping.ChatMessage;
import com.clever.bean.shopping.projo.output.ChatMessageDetailVO;
import com.clever.bean.shopping.projo.output.ConversationDetailVO;
import com.clever.mapper.ConversationMapper;
import com.clever.service.ChatMessageService;
import com.clever.service.ConversationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class ChatWebSocketHandler implements WebSocketHandler {

    private final Map<String, WebSocketSession> sessions = new HashMap<>();
    private static final Logger log = LoggerFactory.getLogger(ChatWebSocketHandler.class);


    private final ChatMessageService chatMessageService;
    private final ConversationService conversationService;

    public ChatWebSocketHandler(ConversationService conversationService, ChatMessageService chatMessageService) {
        this.conversationService = conversationService;
        this.chatMessageService = chatMessageService;
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
        sessions.put(getUserIdFromSession(webSocketSession), webSocketSession);
        webSocketSession.sendMessage(WebSocketMessagePayload.getTextMessage("Connected"));
        List<ConversationDetailVO> list = conversationService.myConversation(getUserIdFromSession(webSocketSession));
        webSocketSession.sendMessage(WebSocketMessagePayload.getTextMessage("ConversationRefresh", JSONUtil.toJsonStr(list)));
    }

    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
        if (JSONUtil.isTypeJSONObject(webSocketMessage.getPayload().toString())) {
            JSONObject object = JSONUtil.parseObj(webSocketMessage.getPayload().toString());
            String type = object.getStr("type");
            switch (type) {
                case "Heart":
                    webSocketSession.sendMessage(WebSocketMessagePayload.getTextMessage("Heart"));
                    break;
                case "Chat":
                    JSONObject contentObj = object.getJSONObject("content");
                    if (contentObj != null) {
                        ChatMessage chatMessage = chatMessageService.send(getUserIdFromSession(webSocketSession), contentObj.getStr("receiverId"), contentObj.getStr("message"));
                        if (chatMessage != null) {
                            WebSocketSession receiverSession = sessions.get(contentObj.getStr("receiverId"));
                            if (receiverSession != null){
                                receiverSession.sendMessage(WebSocketMessagePayload.getTextMessage("Chat", JSONUtil.toJsonStr(chatMessage)));
                            }
                        }
                    }
                    break;
            }
        } else {
            log.info("websocket message 不是规范json字符串");
        }
    }

    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {

    }

    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
        sessions.remove(getUserIdFromSession(webSocketSession));
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    private String getUserIdFromSession(WebSocketSession session) {
        UriComponents components = UriComponentsBuilder.fromUri(session.getUri()).build();
        String userId = components.getQueryParams().getFirst("userId");
        return userId;
    }
}
